package com.hoshiicloud.user.service.impl.rbac;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hoshiicloud.UsersLoginVO;
import com.hoshiicloud.auth.vo.TokenUsersVO;
import com.hoshiicloud.common.aop.Logable;
import com.hoshiicloud.common.exception.CommonError;
import com.hoshiicloud.common.exception.ServiceException;
import com.hoshiicloud.common.rpc.Response;
import com.hoshiicloud.rbac.dto.UserPermissionDTO;
import com.hoshiicloud.rbac.entity.*;
import com.hoshiicloud.rbac.vo.SysUsersVO;
import com.hoshiicloud.user.feign.INeo4jService;
import com.hoshiicloud.user.feign.IdGeneratorService;
import com.hoshiicloud.user.mapper.rbac.*;
import com.hoshiicloud.user.param.rbac.RObject;
import com.hoshiicloud.user.param.rbac.SysUsersQueryParam;
import com.hoshiicloud.user.service.rbac.ISysPermissionesService;
import com.hoshiicloud.user.service.rbac.ISysUsersService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * TODO 事务，缓存，异常控制
 *
 * @Description: 用户服务实现类
 * @author Mr.wu
 * @date: 2019年4月22日 下午6:13:43
 */
@SuppressWarnings("unused")
@Service
@Slf4j
@Configuration
public class SysUsersServiceImpl extends ServiceImpl<SysUsersMapper, SysUsers> implements ISysUsersService {

	@Autowired
	private SysUsersMapper sysUsersMapper;

	@Autowired
	private SysPermissionesMapper sysPermissionesMapper;

	@Autowired
	private SysRolePermissionesMapper sysRolePermissionesMapper;

	@Autowired
	private SysUserRoleMapper sysUserRoleMapper;

	@Autowired
	private SysOrganizationMapper sysOrganizationMapper;

	@Autowired
	private SysRolesMapper sysRolesMapper;


	private INeo4jService neo4JService;

	@Autowired
	private ISysPermissionesService sysPermissionesService;


	private IdGeneratorService idGeneratorRemote;



	@Override
	@Logable(authName = "权限相关-用户信息管理-根据参数查询用户信息")
	public Response<SysUsers> getSysUserByParam(QueryWrapper queryWrapper){
		SysUsers data= sysUsersMapper.selectOne(queryWrapper);
		if(data==null){
			return Response.failed("数据不存在");
		}
		return Response.data(data);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	@CacheEvict(cacheNames = { "sysUser", "sysUserRole" }, allEntries = true)
	@Logable(authName = "权限相关-用户信息管理-新增用户信息")
	public Response addSysUser(SysUsers param,List<String> roleIdList) {
		int count = 0;
		// TODO 判断部门ID是否合法

		// 判断部门是否存在
		SysOrganization dept = sysOrganizationMapper.selectById(param.getDeptId());
		if (dept == null) {
			throw new ServiceException(CommonError.error("部门不存在"));
		}
		String id = idGeneratorRemote.queryGeneratorId();
		if (StringUtils.isBlank(id)) {
			throw new ServiceException(CommonError.error("id服务失败"));
		}
		param.setId(Long.valueOf(id));
		param.setCreatedTime(LocalDateTime.now());
		count = sysUsersMapper.insert(param);
		if (count == 0) {
			throw new ServiceException(CommonError.error("新增失败"));
		}
		// 根据角色ID创建用户权限
		if (roleIdList != null && roleIdList.size() > 0) {
			// 查询id列表是否合规
			QueryWrapper<SysRoles> queryWrapper = new QueryWrapper<SysRoles>();
			// TODO 添加关联ID和分类查询
			queryWrapper.in("id", roleIdList);
			count = sysRolesMapper.selectCount(queryWrapper);
			if (count != roleIdList.size()) {
				// 根据id列表查询到的可用角色不匹配，返回错误
				throw new ServiceException(CommonError.error("可用角色数量不匹配，请刷新重试"));
			}
			// 创建用户和角色的关联
			for (String roleId : roleIdList) {
				SysUserRole entity = new SysUserRole();
				entity.setId(IdWorker.getId());
				entity.setRoleId(Long.valueOf(roleId));
				entity.setUserId(param.getId());
				sysUserRoleMapper.insert(entity);
			}
		}
		//测试暂时跳过
		if(1==2){
			// 插入neo4j节点
			RObject neo4jParam = new RObject();
			// 用户所属部门名称
			neo4jParam.setLabel(dept.getName());
			neo4jParam.setUuid(id);
			neo4jParam.addProperty("uuid", id);
			neo4jParam.addProperty("name", param.getRealName());
			Response result = neo4JService.addRole(neo4jParam);
			if (result != null && !result.isSuccess()) {
				throw new ServiceException(CommonError.error("neo4j服务失败," + result.getMsg()));
			} else if (result == null) {
				throw new ServiceException(CommonError.error("neo4j服务失败"));
			}
		}


		return Response.success("新增成功");
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	@CacheEvict(cacheNames = { "sysUser", "sysUserRole" }, allEntries = true)
	@Logable(authName = "权限相关-用户信息管理-修改用户信息")
	public Response updateSysUser(SysUsers param,List<String> roleIdList) {
		int count = 0;
		// 根据角色ID创建用户权限
		if (roleIdList != null && roleIdList.size() > 0) {
			// 查询id列表是否合规
			QueryWrapper<SysRoles> queryWrapper = new QueryWrapper<SysRoles>();
			// TODO 添加关联ID和分类查询
			queryWrapper.in("id", roleIdList);
			count = sysRolesMapper.selectCount(queryWrapper);
			if (count != roleIdList.size()) {
				// 根据id列表查询到的可用角色不匹配，返回错误
				throw new ServiceException(CommonError.error("可用角色数量不匹配，请刷新重试"));
			}
			// 先删除关联角色
			QueryWrapper<SysUserRole> deleteWrapper = new QueryWrapper<SysUserRole>();
			deleteWrapper.eq("user_id", param.getId());
			sysUserRoleMapper.delete(deleteWrapper);

			// 新增新的关联角色
			// 创建用户和角色的关联
			for (String roleId : roleIdList) {
				SysUserRole entity = new SysUserRole();
				entity.setId(IdWorker.getId());
				entity.setRoleId(Long.valueOf(roleId));
				entity.setUserId(param.getId());
				sysUserRoleMapper.insert(entity);
			}

		}
		sysUsersMapper.updateById(param);
		return Response.success("修改成功");
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	@CacheEvict(cacheNames = { "sysUser", "sysUserRole" }, allEntries = true)
	@Logable(authName = "权限相关-用户信息管理-删除用户信息")
	public Response deleteSysUser(Long id) {
		// 先删除关联角色
		QueryWrapper<SysUserRole> deleteWrapper = new QueryWrapper<SysUserRole>();
		deleteWrapper.eq("user_id", id);
		int count = 0;
		count = sysUserRoleMapper.delete(deleteWrapper);
		if (count == 0) {
			throw new ServiceException("删除失败");
		}
		// 删除用户数据
		count = sysUsersMapper.deleteById(id);
		if (count == 0) {
			throw new ServiceException("删除失败");
		}
		return Response.success("删除成功");
	}

	@Override
	@Cacheable(cacheNames = "sysUser", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#id")
	@Logable(authName = "权限相关-用户信息管理-查询用户信息详情")
	public Response getSysUserDetail(Long id) {
		SysUsers sysUsers = sysUsersMapper.selectById(id);
		if (sysUsers == null) {
			return Response.failed("数据不存在");
		}
		return Response.data(sysUsers);
	}

	@Override
	@Cacheable(cacheNames = "sysUser", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#id")
	@Logable(authName = "权限相关-用户信息管理-查询用户权限列表")
	public Response<UserPermissionDTO> getSysUserPermissionList(Long id) {
		// 获取系统用户关联的角色列表
		QueryWrapper<SysUserRole> queryWrapper_userRole = new QueryWrapper<SysUserRole>();
		List<SysUserRole> roleList = sysUserRoleMapper.selectList(queryWrapper_userRole);
		List<String> permissionValueList = new ArrayList<String>();
		List<String> permissionUrlList=new ArrayList<>();
		UserPermissionDTO userPermissionDTO=new UserPermissionDTO();
		if(roleList.size()>0){
			List<Long> roleIdList = new ArrayList<Long>();
			for (SysUserRole sysUserRole : roleList) {
				roleIdList.add(sysUserRole.getRoleId());
			}

			QueryWrapper<SysRolePermissiones> queryWrapper_rolePer = new QueryWrapper<SysRolePermissiones>();
			queryWrapper_rolePer.in("role_id", roleIdList);
			List<SysRolePermissiones> rolePermissionesList = sysRolePermissionesMapper.selectList(queryWrapper_rolePer);
			if(rolePermissionesList.size()>0){
				// 根据角色ID列表组装权限ID列表
				List<Long> permissionIdList = new ArrayList<Long>();
				for (SysRolePermissiones sysRolePermissiones : rolePermissionesList) {
					permissionIdList.add(sysRolePermissiones.getPermissionId());
				}
				// 根据权限ID列表取得权限值列表
				List<SysPermissiones> permissionesList = sysPermissionesMapper.selectBatchIds(permissionIdList);

				if (permissionIdList.size() != permissionesList.size()) {
					throw new ServiceException("角色权限跟可用权限不匹配");
				}

				for (SysPermissiones sysPermissiones : permissionesList) {
					if(sysPermissiones.getStatus()==1){
						//返回可用状态的权限
						permissionValueList.add(sysPermissiones.getPermissionValue());
						permissionUrlList.add(sysPermissiones.getUri());
					}
				}
			}
		}
		userPermissionDTO.setPermissionUrlList(permissionUrlList);
		userPermissionDTO.setPermissionValueList(permissionValueList);
		return Response.data(userPermissionDTO);
	}

	@Override
	@Cacheable(cacheNames = "sysUser", key = "T(com.hoshiicloud.common.utils.DigestUtils).md5('Wrapper(SqlSelect=' + #queryWrapper.getSqlSelect() + ', SqlSegment=' + #queryWrapper.getSqlSegment() + ')')")
	@Logable(authName = "权限相关-用户信息管理-查询用户信息列表")
	public Response getSysUserList(QueryWrapper<SysUsers> queryWrapper) {
		List<SysUsers> list = sysUsersMapper.selectList(queryWrapper);
		return Response.data(list);
	}

	@Override
	@Cacheable(cacheNames = "sysUser", key = "T(com.hoshiicloud.common.utils.DigestUtils).md5(#key)")
	@Logable(authName = "权限相关-用户信息管理-分页查询用户信息")
	public Response getPage(IPage<SysUsers> page, QueryWrapper<SysUsers> queryWrapper,String key) {
		return Response.data(sysUsersMapper.selectPage(page, queryWrapper));
	}

	@Override
	public TokenUsersVO getLoginDetail(String username) {
		QueryWrapper<SysUsers> tq = new QueryWrapper<>();
		tq.lambda().eq( SysUsers::getUsername, username);
		SysUsers sysUsers = this.getOne(tq);
		if (null == sysUsers) {
			throw new ServiceException("用户信息为空："+username);
		}

		/*
		Response<UserPermissionDTO> test = this.getSysUserPermissionList(sysUsers.getId());
		UserPermissionDTO userPermissionDTO = test.getData();
		sysUsersLoginVO.setPermissionValueList(userPermissionDTO.getPermissionValueList());
		sysUsersLoginVO.setPermissionUrlList(userPermissionDTO.getPermissionUrlList());
		 */
		List<SysRoles> listRoles = sysRolesMapper.getRolesByUserId(sysUsers.getId());
		//List<String> listRoleIds = listRoles.stream().map(role -> role.getId().toString()).collect(Collectors.toList());
		List<String> listRoleNames = listRoles.stream().map(role -> role.getName()).collect(Collectors.toList());


		List<SysPermissiones> listPem = sysPermissionesService.getSysPermissionesByUserId(sysUsers.getId());
		List<String> pemValueList = listPem.stream().filter(per -> StringUtils.isNotBlank(per.getUri()))
				.map(SysPermissiones::getPermissionValue).collect(Collectors.toList());
		List<String> urlList = listPem.stream().filter(per -> StringUtils.isNotBlank(per.getUri()))
				.map(SysPermissiones::getUri).collect(Collectors.toList());

		TokenUsersVO sysUsersLoginVO = new TokenUsersVO();
		BeanUtils.copyProperties(sysUsers, sysUsersLoginVO);
		sysUsersLoginVO.setUserId(sysUsers.getId());
		sysUsersLoginVO.setPemValueList(pemValueList);
		sysUsersLoginVO.setUrlList(urlList);
		sysUsersLoginVO.setRoleList(listRoleNames);
		return sysUsersLoginVO;
	}
	/**
	 *
	 * @Description: SAAS系统分页查询所有员工列表
	 * @author rogercj
	 * @param page
	 * @param sysUsersQueryParam
	 * @return Response<IPage<SysUsers>>
	 */
	@Override
	public IPage<SysUsersVO> getAllEmployee(IPage<SysUsers> page, SysUsersQueryParam sysUsersQueryParam){
		return sysUsersMapper.getAllEmployee(page,sysUsersQueryParam);
	}

	/**
	 *
	 * @Description: SAAS系统根据部门ID分页查询(包括子部门)员工列表
	 * @author rogercj
	 * @param page
	 * @param sysUsersQueryParam
	 * @return Response<IPage<SysUsers>>
	 * @date: 2019年8月8日 下午5:30:49
	 */
	@Override
	public IPage<SysUsersVO> getPageByDeptId(IPage<SysUsers> page, SysUsersQueryParam sysUsersQueryParam){
		return sysUsersMapper.getEmployeeByDeptId(page,sysUsersQueryParam);
	}

	/**
	 *
	 * @Description: SAAS系统根据角色名称分页查询员工列表
	 * @author rogercj
	 * @param page
	 * @param sysUsersQueryParam
	 * @return Response<IPage<SysUsers>>
	 * @date: 2019年8月8日 下午5:30:49
	 */
	@Override
	public IPage<SysUsersVO> getPageByRoleName(IPage<SysUsers> page, SysUsersQueryParam sysUsersQueryParam){
		return sysUsersMapper.getEmployeeByRoleName(page,sysUsersQueryParam);
	}

}
